<!-- 
  该组件是一个 无渲染组件，主要处理 正在热映与即将上映 两个列表数据的获取与加载更多
 -->
<template>
  <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
    <van-list
      v-model:loading="loading"
      v-model:error="error"
      :finished="finished"
      finished-text="没有更多了"
      error-text="请求出错，点击重试"
      offset="50"
      @load="onLoad"
    >
      <slot v-for="item in list" :key="item" v-bind="item"></slot>
    </van-list>
  </van-pull-refresh>
</template>

<script lang="ts" setup>
import { ref, reactive, watch } from "vue";
import { apiGet } from "@/utils/request";
import useStore from "@/hooks/useStore";

const { city } = useStore();

const props = defineProps<{
  type: number;
}>();

// 当前是否正在 load 中
const loading = ref(false);
// 当前是否已经全部加载完成，没有更多了
const finished = ref(false);
// 当前请求是否出现异常
const error = ref(false);
// 当前是否处于下拉刷新中
const refreshing = ref(false);
// 当前加载出来的数据
const list = ref<IFilm[]>([]);

const state = reactive({
  pageNum: 1,
  pageSize: 10,
});

// 加载数据的方法
async function onLoad() {
  try {
    const data = await apiGet<{
      films: IFilm[];
      total: number;
    }>("mall.film-ticket.film.list", {
      cityId: city.selectedCity.cityId, // 城市Id
      type: props.type, // 电影类型，1-正在热映，2-即将上映
      pageNum: state.pageNum, // 当前页码
      pageSize: state.pageSize, // 每页条数
    });

    // 将数据追加到 list
    list.value =
      state.pageNum === 1 ? data.films : [...list.value, ...data.films];

    // 将 state.pageNum++
    state.pageNum++;

    // 判断 list.value 的长度，是否 >= data.total
    if (list.value.length >= data.total) {
      finished.value = true;
    }
  } catch (err) {
    error.value = true;
  } finally {
    // 将 loading 状态设置为 false，表示这次加载完成
    loading.value = false;
    // 将 refreshing 状态设置为 false
    refreshing.value = false;
  }
}

// 下拉刷新
function onRefresh() {
  // 将 页码重置为 1
  state.pageNum = 1;
  // 将 finished 重置为 false
  finished.value = false;

  loading.value = true;
  // 主动调用 onLoad
  onLoad();
}

// 监听当前选择的城市的变化，刷新数据
watch(
  () => city.selectedCity.cityId,
  () => {
    onRefresh();
  }
);
</script>
